#include <algorithm>
#include <iostream>
#include "Master.h"
#include "TwoWayList.cc"

using namespace std;

MasterImp::MasterImp(void)
#ifdef DEBUG_EVPROC
: EventProcessorImp(true,"Master") // comment to remove debug
#endif
{
  
  // register the message function
  RegisterMessageProcessor(DieMessage::type, &Die, 0 /* priority */);

  RegisterMessageProcessor(GenDoneMessage::type, &GenDone, 1 /* priority */);
  
  RegisterMessageProcessor(FillMessage::type, &PushNumber, 2 /* priority */);
  
  RegisterMessageProcessor(DoneMessage::type, &SumDone, 3 /* priority */);

  RegisterMessageProcessor(WorkerDoneMessage::type, &WorkerDone, 4 /* priority */);

  sum = 0;
	
  generatorsDone = false;

  current = 0;

  numWorkers = 0;	

}

void MasterImp::CreateWorker(){
	vector<int> xWork;
	vector<int>::iterator xit;
	for(xit = buffer.begin()+current;xit != buffer.begin()+current+10;++xit){

	xWork.push_back(*xit);

	}	
	

	//EventProcessor myInterfClone;
	//myInterfClone.CopyFrom(myInterface);

	Worker newWorker(myInterface,xWork);
	newWorker.ForkAndSpin();	
	myWorkers.Insert(newWorker);
	
	
	++numWorkers;

}
//Handling the fill message from the Generator

MESSAGE_HANDLER_DEFINITION_BEGIN(MasterImp, PushNumber, FillMessage)
	
	evProc.buffer.push_back(msg.number);
	
	int bufferSize = (int)evProc.buffer.size();
	// Here we send the vector if 10 elements are added to the vector
	if(bufferSize%10 == 0 ){
		
		evProc.CreateWorker();
		evProc.current += 10;
	}
	
	EventProcessor myInterfClone;
	myInterfClone.CopyFrom(evProc.myInterface);

	NextNumberMessage_Factory(msg.sender,0,myInterfClone);

MESSAGE_HANDLER_DEFINITION_END


MESSAGE_HANDLER_DEFINITION_BEGIN(MasterImp, WorkerDone, WorkerDoneMessage)
	
	--evProc.numWorkers;
	if(evProc.numWorkers == 0 && evProc.generatorsDone){
		evProc.Seppuku();
	}

MESSAGE_HANDLER_DEFINITION_END
//Handling the message sent by worker signalling sum is done

MESSAGE_HANDLER_DEFINITION_BEGIN(MasterImp, SumDone, DoneMessage)
	
	evProc.sum += msg.sum;
	//cout<<"Sum here is "<<evProc.sum<<endl;
	KillEvProc(msg.sender);	

MESSAGE_HANDLER_DEFINITION_END

MESSAGE_HANDLER_DEFINITION_BEGIN(MasterImp, GenDone, GenDoneMessage)
		
	evProc.generatorsDone = true;
	cout<<"Got GenDone Message - Master"<<endl;

MESSAGE_HANDLER_DEFINITION_END

MESSAGE_HANDLER_DEFINITION_BEGIN(MasterImp, Die, DieMessage)

	cout<<"The sum is "<<evProc.sum<<endl;
	cout<<"The total number of workers created "<<evProc.myWorkers.Length()<<endl;
	evProc.EventProcessorImp::processDieMessage(evProc,msg);

MESSAGE_HANDLER_DEFINITION_END

